package tij4.concurrent.exercise.ex28;

/*
    修改TestBlockQueue,添加一个将LiftOff放置到BlockingQueue中的任务,
    不要放置到main()中
 */

import tij4.concurrent.pojo.LiftOff;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.*;

class LiftOffRunner implements Runnable {
    private BlockingQueue<LiftOff> rockets;

    public LiftOffRunner(BlockingQueue<LiftOff> rockets) {
        this.rockets = rockets;
    }
    public void add(LiftOff liftOff) {
        try {
            rockets.put(liftOff);
        }catch (InterruptedException e) {
            System.out.println("Interrupted during put()");
        }
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {
                LiftOff liftOff = rockets.take();
                liftOff.run();  //使用此线程
            }
        }catch (InterruptedException e) {
            System.out.println("Waking from take()");
        }
        System.out.println("Exiting LiftOffRunner");
    }
}

class LiftOffAdder implements Runnable {
    private LiftOffRunner liftOffRunner;

    public LiftOffAdder(LiftOffRunner liftOffRunner) {
        this.liftOffRunner = liftOffRunner;
    }

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            liftOffRunner.add(new LiftOff());
        }
    }
}

public class TestBlockQueues {
    static void getKey() {
        try {
            new BufferedReader(
                    new InputStreamReader(System.in)
            ).readLine();

        }catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    static void getKey(String msg) {
        System.out.println(msg);
        getKey();
    }
    static void test(String msg, BlockingQueue<LiftOff> queue) {
        System.out.println(msg);
        LiftOffRunner liftOffRunner = new LiftOffRunner(queue);
        LiftOffAdder liftOffAdder = new LiftOffAdder(liftOffRunner);
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(liftOffRunner);
        executorService.execute(liftOffAdder);

        getKey("Press 'Enter' (" + msg + ")");  //等待用户响应,使程序阻塞
        System.out.println("Finished " + msg + " test");
        executorService.shutdownNow();
    }

    public static void main(String[] args) {
        test("LinkedBlockingQueue", new LinkedBlockingQueue<LiftOff>());
        test("ArrayBlockingQueue", new ArrayBlockingQueue<LiftOff>(3));
        test("SynchronousQueue", new SynchronousQueue<LiftOff>());  //容量为1
    }
}
